package main

import (
	"database/sql"
	"io"
	"log"

	"github.com/gin-gonic/gin"

	_ "github.com/go-sql-driver/mysql"
)

func initializeDatabase() (*sql.DB, error) {
	dsn := "root:123456@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := sql.Open("mysql", dsn)

	if err != nil {
		return nil, err
	}
	// 建立连接
	if err = db.Ping(); err != nil {
		log.Println("connect 2 database fail...")
		return nil, io.EOF
	}
	return db, nil
}

type users struct {
	Id   uint64 `json:"id"`
	Name string `json:"name"`
	Age  uint32 `json:"age"`
}

// 查询单条数据
func querySingleRow(db *sql.DB) users {
	sqlStr := "select  * from users where id = ?"
	var u users
	if err := db.QueryRow(sqlStr, 1).Scan(&u.Id, &u.Name, &u.Age); err != nil {
		log.Printf("scan faild err：%v\n", err)
		return u
	}
	log.Printf("查询结果：%v,%v,%v", u.Id, u.Name, u.Age)
	return u
}

// 查询多行数据
func queryMutiRow(db *sql.DB) []users {
	sqlStr := "select  * from users"
	rows, err := db.Query(sqlStr)
	if err != nil {
		log.Printf("queryMutiRow faild err：%v\n", err)
		panic(err)
	}
	defer rows.Close()
	usersR := make([]users, 0)
	for rows.Next() {
		var u users
		err := rows.Scan(&u.Id, &u.Name, &u.Age)
		if err != nil {
			log.Printf("scan faild err：%v\n", err)
			panic(err)
		}
		usersR = append(usersR, u)
	}
	log.Printf("查询结果：%v", usersR)
	return usersR

}

// 更新
func updateRow(db *sql.DB) {
	sqlStr := "update users set name=? where id = ?"
	res, err := db.Exec(sqlStr, "小花", 1)
	if err != nil {
		log.Printf("updateRow faild err：%v\n", err)
		panic(err)
	}
	n, err := res.RowsAffected()
	log.Printf("updateRow 受影响的行数：%v\n", n)
	log.Println("updateRow success")
}

func deleteRow(db *sql.DB) {
	sqlStr := "delete from users where id= ?"
	res, err := db.Exec(sqlStr, 1)
	if err != nil {
		log.Printf("deleteRow faild err：%v\n", err)
		panic(err)

	}
	n, err := res.RowsAffected()
	if err != nil {
		log.Printf("get RowsAffected faild err：%v\n", err)
		panic(err)

	}
	log.Printf("deleteRow 受影响的行数：%v\n", n)
	log.Println("deleteRow success")

}

func insertRow(db *sql.DB) {
	sqlStr := "insert into users (id,name,age) values (?,?,?)"
	res, err := db.Exec(sqlStr, 7, "小七", 70)
	if err != nil {
		log.Printf("insertRow faild err：%v\n", err)

	}
	id, err := res.LastInsertId()
	if err != nil {
		log.Printf("insertRow faild err：%v\n", err)
		panic(err)
	}
	log.Printf("insert success. id: %v\n", id)
}
func main() {
	db, err := initializeDatabase()
	if err != nil {
		panic(err)
	}
	log.Println("connect 2 database success.")
	r := gin.Default()
	// 查询单行
	r.GET("user", func(c *gin.Context) {
		u := querySingleRow(db)
		c.JSON(200, gin.H{
			"data": u,
		})
	})
	// 查询多行
	r.GET("users", func(c *gin.Context) {
		u := queryMutiRow(db)
		c.JSON(200, gin.H{
			"data": u,
		})
	})
	// 更新
	//updateRow(db)
	//deleteRow(db)
	insertRow(db)
	r.Run()
}
